%{
#include <string.h>
#include <stdlib.h>

#include "uarch/enums.h"
#include "uarch/module.h"
#include "uarch/settings.h"
#include "settings.tab.h"

extern setts identifiers[];
char *end_ptr;

int find_id (char * str) 
{
	int i = 0;

	while (strcmp(identifiers[i].name,"end"))
    {
		if (!strcmp(str,identifiers[i].name))
        {
			return i;
		}
		i++;
	}
	return -1;
}

%}

%%
"CACHE_DATA"        { yylval.enumeration = CACHE_DATA; return ENUMERATION; }
"CACHE_TAG"         { yylval.enumeration = CACHE_TAG; return ENUMERATION; }

"INVALID_PRED"      { yylval.enumeration = INVALID_PRED; return ENUMERATION; }
"THRESHOLD_PRED"    { yylval.enumeration = THRESHOLD_PRED; return ENUMERATION; }

"INVALID_SCOPE"     { yylval.enumeration = INVALID_SCOPE; return ENUMERATION; }
"NODE_SCOPE"        { yylval.enumeration = NODE_SCOPE; return ENUMERATION; }
"NHOOD_SCOPE"       { yylval.enumeration = NHOOD_SCOPE; return ENUMERATION; }
"GLOBAL_SCOPE"      { yylval.enumeration = GLOBAL_SCOPE; return ENUMERATION; }

"module_tiers"      { return MODULE_TIERS; }
"NI_M"              { yylval.module_index = NI_M;         return MODULE_INDEX; }
"PR_M"              { yylval.module_index = PR_M;         return MODULE_INDEX; }
"L1_M"              { yylval.module_index = L1_M;         return MODULE_INDEX; }
"L2_M"              { yylval.module_index = L2_M;         return MODULE_INDEX; }
"L3_M"              { yylval.module_index = L3_M;         return MODULE_INDEX; }
"MC_M"              { yylval.module_index = MC_M;         return MODULE_INDEX; }
"INVALID_M"         { yylval.module_index = INVALID_M;    return MODULE_INDEX; }

"INVALID_MAP"       { yylval.enumeration = INVALID_MAP;     return ENUMERATION; }
"ROUND_ROBIN_MAP"   { yylval.enumeration = ROUND_ROBIN_MAP;	return ENUMERATION; }
"SEQUENTIAL_MAP"    { yylval.enumeration = SEQUENTIAL_MAP;  return ENUMERATION; }

"MSI"               { yylval.enumeration = MSI;           return ENUMERATION; }
"MESI"              { yylval.enumeration = MESI;          return ENUMERATION; }
"MOSI"              { yylval.enumeration = MOSI;          return ENUMERATION; }
"LRU"               { yylval.enumeration = RP_LRU;        return ENUMERATION; }
"CACHE_SHARED"      { yylval.enumeration = CACHE_SHARED;  return ENUMERATION; }
"CACHE_PRIVATE"     { yylval.enumeration = CACHE_PRIVATE; return ENUMERATION; }
"NODE_CORE"         { yylval.enumeration = NODE_CORE;     return ENUMERATION; }
"NODE_MC"           { yylval.enumeration = NODE_MC;       return ENUMERATION; }
"L2SHARED"          { yylval.enumeration = L2SHARED;      return ENUMERATION; }
"L2PRIVATE"         { yylval.enumeration = L2PRIVATE;     return ENUMERATION; }
"DIR_1L"            { yylval.enumeration = DIR_1L;        return ENUMERATION; }
"DIR_2L_FULL_REP"   { yylval.enumeration = DIR_2L_FULL_REP; return ENUMERATION; }
"DIR_2L_SELECT_REP" { yylval.enumeration = DIR_2L_SELECT_REP; return ENUMERATION; }
"MESH_STANDARD"     { yylval.enumeration = MESH_STANDARD;     return ENUMERATION; }
"EXPRESS_MESH"      { yylval.enumeration = EXPRESS_MESH;      return ENUMERATION; }
"CN_TORUS"             { yylval.enumeration = CN_TORUS;      return ENUMERATION; }
"FLAT_MESH"         { yylval.enumeration = FLAT_MESH;     return ENUMERATION; }
"PIRANHA"           { yylval.enumeration = PIRANHA;       return ENUMERATION; }
"SUPERDOME"         { yylval.enumeration = SUPERDOME;      return ENUMERATION; }
"COUT"              { yylval.enumeration = OUTPUT_FMT_COUT; return ENUMERATION; }
"CERR"              { yylval.enumeration = OUTPUT_FMT_CERR; return ENUMERATION; }
"CSV"               { yylval.enumeration = OUTPUT_FMT_CSV; return ENUMERATION; }
"NONE"              { yylval.enumeration = OUTPUT_FMT_NONE; return ENUMERATION; }
"true"              { yylval.boolean = true;              return BOOLEAN; }
"false"             { yylval.boolean = false;             return BOOLEAN; }
[0-9]+              { yylval.number = atoll (yytext);     return NUMBER; }
0x[0-9|a-f|A-F]+    { char *ptr; yylval.number = strtoll (yytext, &ptr, 16); return NUMBER; }
"ALLOCATE"          { return ALLOCATE; }
"["                 { return LBRACKET; }
"]"                 { return RBRACKET; }
"{"                 { return LBRACE; }
"}"                 { return RBRACE; }
"("                 { return LPARA; }
")"                 { return RPARA; }
"<<"                { return LSHIFT; }
","                 { return COMMA; }
":"                 { return COLON; }

[a-zA-Z]([a-zA-Z]|[0-9]|_)+  {

    int id;
    if ((id = find_id (yytext)) != -1)
    { 
      yylval.ident = id;
      return IDENTIFIER;
    }
    else 
    {
      fprintf (stderr, "Could not find identifier (%s)\n", yytext);
      exit(-1);
    }
  }

[ \t\n]+	  { ; }
%%

